<template>
    <el-container>
        <el-main style="display: flex; flex-direction: column; height: 100%; background: #ffffff;">
            <!-- 聊天内容滚动区域 -->
            <div ref="chatContainer" class="messagesBox">
                <div v-for="(message, index) in messages" :key="index" class="itemBox">
                    <!-- 用户消息 -->
                    <div v-if="message.role === 'user'" style="justify-content: flex-end;">
                        <el-card shadow="always" class="userItemBox">
                            <div>{{ message.content }}</div>
                        </el-card>
                    </div>

                    <!-- AI 消息 -->
                    <div v-else style="display: flex;flex-direction: column;margin-top: 20px;">
                        <Loading v-if="isLatestAssistant(index) && isLoading" />
                        <div v-if="parseContent(message).think" class="thinkingBox"
                            v-html="renderMarkdown(parseContent(message).think)"></div>
                        <div class="answerLine" v-html="renderMarkdown(parseContent(message).answer)"></div>
                    </div>
                </div>
            </div>

            <!-- 输入区域 -->
            <div class="inputBox">
                <div class="inputMainBox">
                    <div class="textareaWrapper">
                        <textarea v-model="userInput" ref="textareaRef" class="chatTextarea" placeholder="询问任何问题"
                            @input="autoResize" @keydown="handleKeyDown"></textarea>

                        <div class="chatTool">
                            <button class="sendButton" @click="handleSend">
                                <svg viewBox="0 0 24 24" width="20" height="20" fill="white">
                                    <path d="M2 21l21-9L2 3v7l15 2-15 2v7z"></path>
                                </svg>
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </el-main>
    </el-container>
</template>

<script>
import { threadsApi } from '../../api/aigc/index';
import MarkdownIt from 'markdown-it';
import mk from 'markdown-it-katex';
import 'katex/dist/katex.min.css';
import Loading from './loading.vue'

const md = new MarkdownIt({ html: true, linkify: true, breaks: true }).use(mk);

export default {
    components: {
        Loading
    },
    props: {
        currentWorkspaceSlug: String,
        currentThread: Object
    },
    data() {
        return {
            messages: [],
            userInput: '',
            streamId: null,
            controller: null,
            isLoading: false,
        };
    },
    watch: {
        currentThread: {
            immediate: true,
            handler(val) {
                if (val && val.slug) {
                    this.loadMessages();
                }
            }
        }
    },
    methods: {
        async loadMessages() {
            try {
                const res = await threadsApi.getThreadChats(this.currentWorkspaceSlug, this.currentThread.slug);
                this.messages = res.history || [];
                this.$nextTick(this.scrollToBottom);
            } catch (err) {
                this.$message.error('加载聊天失败');
            }
        },
        parseContent(message) {
            if (message.role !== 'assistant') return { think: null, answer: message.content };
            const thinkMatch = message.content.match(/<think>([\s\S]*?)<\/think>/);
            const think = thinkMatch ? thinkMatch[1].trim() : null;
            const answer = message.content.replace(/<think>[\s\S]*?<\/think>/, '').trim();
            return { think, answer };
        },
        renderMarkdown(text) {
            return md.render(text || '');
        },
        async handleSend() {
            if (!this.userInput.trim()) return;
            const question = this.userInput.trim();
            this.userInput = '';
            this.messages.push({ role: 'user', content: question });
            this.$nextTick(this.scrollToBottom);
            this.startStreaming(question);
        },
        scrollToBottom() {
            const el = this.$refs.chatContainer;
            if (el) el.scrollTop = el.scrollHeight;
        },
        autoResize() {
            const textarea = this.$refs.textareaRef;
            if (!textarea) return;
            textarea.style.height = 'auto';
            const scrollHeight = textarea.scrollHeight;
            const minHeight = 50;
            const maxHeight = 200;
            textarea.style.height = Math.min(Math.max(scrollHeight, minHeight), maxHeight) + 'px';
            textarea.style.overflowY = scrollHeight > maxHeight ? 'auto' : 'hidden';
        },
        async startStreaming(question) {
            this.controller = new AbortController();
            const signal = this.controller.signal;

            let result = ''; // To accumulate the response
            let done = false;
            let isThinking = false; // To track if we are in thinking phase

            try {
                const response = await fetch(`http://localhost:3001/api/v1/workspace/${this.currentWorkspaceSlug}/thread/${this.currentThread.slug}/stream-chat`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Accept': 'text/event-stream',
                        'Authorization': 'Bearer J644T01-ZEC4C6T-KPNE8WC-6BSG3JE',
                    },
                    body: JSON.stringify({
                        message: question,
                        mode: 'chat'
                    }),
                    signal: signal,
                });

                //思考动画
                this.isLoading = true;

                const reader = response.body.getReader();
                const decoder = new TextDecoder('utf-8');

                // Initialize a message object that will be updated with new text chunks.
                let currentMessage = {
                    role: 'assistant',
                    content: '',
                    type: 'think', // Assume it's thinking initially.
                };

                // Immediately push the initial "thinking" message.
                this.messages.push(currentMessage);

                while (!done) {
                    const { value, done: streamDone } = await reader.read();
                    done = streamDone;
                    const chunk = decoder.decode(value, { stream: true });

                    if (chunk) {
                        //如果有结果 停止加载动画
                        this.isLoading = false;

                        const responseData = chunk.split('data: ')[1]; // Extract the actual response data after "data: "
                        if (responseData) {
                            try {
                                const parsedData = JSON.parse(responseData);
                                if (parsedData.type === 'textResponseChunk') {
                                    const { textResponse, close } = parsedData;

                                    // Append the new text chunk to the content
                                    currentMessage.content += textResponse;

                                    // Check if it's thinking or answering
                                    isThinking = textResponse.includes('<think>') ? true : false;
                                    currentMessage.type = isThinking ? 'think' : 'answer';

                                    // Whenever a chunk is added, update the message list
                                    this.$set(this.messages, this.messages.length - 1, currentMessage); // Ensure we update the latest message

                                    // When stream is done (close = true), break out of loop
                                    if (close) {
                                        break;
                                    }
                                }
                            } catch (err) {
                                console.error('Error parsing chunk:', err);
                            }
                        }
                    }
                }

                // Optionally scroll to the bottom after finishing
                this.$nextTick(this.scrollToBottom);
            } catch (error) {
                if (this.controller.signal.aborted) {
                    console.log('Request was aborted');
                } else {
                    console.error('Streaming request failed:', error);
                    this.$message.error('AI响应失败');
                }
            }
        }
        ,

        // Cancel the current request if necessary
        cancelRequest() {
            if (this.controller) {
                this.controller.abort();
            }
        },

        handleKeyDown(e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                this.handleSend();
            }
        },
        isLatestAssistant(index) {
            // 找最后一个 assistant 消息的 index
            for (let i = this.messages.length - 1; i >= 0; i--) {
                if (this.messages[i].role === 'assistant') {
                    return i === index;
                }
            }
            return false;
        }
    }
};
</script>

<style scoped>
.messagesBox {
    flex: 1;
    overflow-y: auto;
    padding: 0px 50px;
}

.userItemBox {
    background-color: #e9e9e980;
    border-radius: 20px;
    display: inline-block;
    max-width: 70%;
}

.aiItemBox {
    margin: 20px 0px;
}

.itemBox {
    margin: 0px 50px;
}

.itemBox>div {
    display: flex;
    min-width: 500px;
}

.inputBox {
    padding: 0px 50px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.inputMainBox {
    margin: 0px 50px;
    width: 100%;
    position: relative;
    display: flex;
    flex-direction: column;
}

.textareaWrapper {
    position: relative;
    width: 100%;
    border-radius: 30px;
    border: 1px solid #ddd;
    box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
    padding: 10px;
    margin-bottom: 5px;
}

.chatTextarea {
    width: 100%;
    min-height: 30px;
    max-height: 200px;
    padding: 5px 0px 7px 5px;
    border: none;
    border-radius: 8px;
    resize: none;
    overflow-y: auto;
    font-size: 16px;
    outline: none;
    line-height: 1.5;
    color: #1a1a1a;
    transition: height 0.2s ease;
}

.sendButton {
    background-color: black;
    border: none;
    border-radius: 50%;
    width: 30px;
    height: 30px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

.sendButton:hover {
    background-color: #333;
}

.chatTool {
    display: flex;
    justify-content: flex-end;
}

.thinkingBox {
    background-color: #f2f2f2;
    color: #666;
    border-radius: 6px;
    padding: 12px;
    margin-bottom: 10px;
    font-size: 14px;
    font-style: italic;
    text-align: start;
}

.answerLine {
    font-size: 16px;
    color: #333;
    line-height: 1.6;
    margin-top: 10px;
    text-align: start;
}
</style>
